package cn.itrip.biz.service.itripHotelOrder;
import cn.itrip.beans.pojo.ItripHotelOrder;
import cn.itrip.beans.pojo.ItripHotelTempStore;
import cn.itrip.beans.pojo.ItripOrderLinkUser;
import cn.itrip.beans.pojo.ItripUserLinkUser;
import cn.itrip.beans.vo.order.ItripListHotelOrderVO;
import cn.itrip.common.BigDecimalUtil;
import cn.itrip.common.EmptyUtils;
import cn.itrip.common.Page;
import cn.itrip.dao.itripHotelOrder.ItripHotelOrderMapper;
import cn.itrip.dao.itripHotelRoom.ItripHotelRoomMapper;
import cn.itrip.dao.itripOrderLinkUser.ItripOrderLinkUserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import static java.math.BigDecimal.ROUND_DOWN;


import cn.itrip.common.Constants;
@Service
public class ItripHotelOrderServiceImpl implements ItripHotelOrderService {

    @Resource
    private ItripHotelOrderMapper itripHotelOrderMapper;
    @Resource
    private ItripHotelRoomMapper itripHotelRoomMapper;
    @Resource
    private ItripOrderLinkUserMapper itripOrderLinkUserMapper;

    public ItripHotelOrder getItripHotelOrderById(Long id)throws Exception{
        return itripHotelOrderMapper.getItripHotelOrderById(id);
    }

    public List<ItripHotelOrder>	getItripHotelOrderListByMap(Map<String,Object> param)throws Exception{
        return itripHotelOrderMapper.getItripHotelOrderListByMap(param);
    }

    public Integer getItripHotelOrderCountByMap(Map<String,Object> param)throws Exception{
        return itripHotelOrderMapper.getItripHotelOrderCountByMap(param);
    }

    public Map<String, String> itriptxAddItripHotelOrder(ItripHotelOrder itripHotelOrder, List<ItripUserLinkUser> linkUsers)throws Exception{
        Map<String, String> output = new HashMap<>();
        //新增
        if(itripHotelOrder.getId() == null){
            itripHotelOrder.setCreationDate(new Date());
            itripHotelOrderMapper.insertItripHotelOrder(itripHotelOrder);
        }else{//修改
            //删除旧的linkuser
            itripOrderLinkUserMapper.deleteItripOrderLinkUserById(itripHotelOrder.getId());
            //修改订单
            itripHotelOrder.setModifyDate(new Date());
            itripHotelOrderMapper.updateItripHotelOrder(itripHotelOrder);
        }
        //订单关联用户orderlinkuser
        if(EmptyUtils.isNotEmpty(linkUsers)){
            ItripOrderLinkUser orderUser = null;
            for(ItripUserLinkUser linkUser:linkUsers){
                orderUser = new ItripOrderLinkUser();
                BeanUtils.copyProperties(linkUser,orderUser);
                orderUser.setOrderId(itripHotelOrder.getId());
                orderUser.setLinkUserId(linkUser.getId());
                orderUser.setCreationDate(new Date());
                orderUser.setCreatedBy(linkUser.getId());
                itripOrderLinkUserMapper.insertItripOrderLinkUser(orderUser);
            }
        }
        output.put("id",itripHotelOrder.getId().toString());
        output.put("orderNo",itripHotelOrder.getOrderNo());
        return output;
    }

    //???是否需要抽象出更新实时库存表的方法???
    public Integer itriptxModifyItripHotelOrder(ItripHotelOrder itripHotelOrder)throws Exception{
        //查询需要变更的订单
        ItripHotelOrder orderToModify = itripHotelOrderMapper.getItripHotelOrderById(itripHotelOrder.getId());
        //变更实时库存表
        Map<String, Object> param = new HashMap<>();
        param.put("count", orderToModify.getCount());
        param.put("roomId", orderToModify.getRoomId());
        param.put("startDate", orderToModify.getCheckInDate());
        param.put("endDate", orderToModify.getCheckOutDate());
        itripHotelOrderMapper.flushTempStore(param);
        //更新订单表
        itripHotelOrder.setModifyDate(new Date());
        return itripHotelOrderMapper.updateItripHotelOrder(itripHotelOrder);
    }

    public Integer itriptxDeleteItripHotelOrderById(Long id)throws Exception{
        return itripHotelOrderMapper.deleteItripHotelOrderById(id);
    }

    public Page<ItripHotelOrder> queryItripHotelOrderPageByMap(Map<String,Object> param, Integer pageNo, Integer pageSize)throws Exception{
        Integer total = itripHotelOrderMapper.getItripHotelOrderCountByMap(param);
        pageNo = EmptyUtils.isEmpty(pageNo) ? Constants.DEFAULT_PAGE_NO : pageNo;
        pageSize = EmptyUtils.isEmpty(pageSize) ? Constants.DEFAULT_PAGE_SIZE : pageSize;
        Page page = new Page(pageNo, pageSize, total);
        param.put("beginPos", page.getBeginPos());
        param.put("pageSize", page.getPageSize());
        List<ItripHotelOrder> itripHotelOrderList = itripHotelOrderMapper.getItripHotelOrderListByMap(param);
        page.setRows(itripHotelOrderList);
        return page;
    }

    public Page<ItripListHotelOrderVO> getHotelOrderListVoPageByMap(Map<String,Object> param, Integer pageNo, Integer pageSize)throws Exception{
        Integer total = itripHotelOrderMapper.getItripHotelOrderCountByMap(param);
        pageNo = EmptyUtils.isEmpty(pageNo) ? Constants.DEFAULT_PAGE_NO : pageNo;
        pageSize = EmptyUtils.isEmpty(pageSize) ? Constants.DEFAULT_PAGE_SIZE : pageSize;
        Page page = new Page(pageNo, pageSize, total);
        param.put("beginPos", page.getBeginPos());
        param.put("pageSize", page.getPageSize());
        List<ItripListHotelOrderVO> itripHotelOrderList = itripHotelOrderMapper.getHotelOrderListVoByMap(param);
        page.setRows(itripHotelOrderList);
        return page;
    }

    @Override
    public List<ItripHotelTempStore> queryRoomStore(Map<String, Object> param) throws Exception {
        //完善实时库存表，调用存储过程，自定义mapper方法
        itripHotelOrderMapper.flushStore(param);
        //结合实时库存表和订单表的临时记录（未支付）计算每一天的真实库存，自定义mapper方法
        return itripHotelOrderMapper.queryRoomStore(param);
    }

    @Override
    public boolean validateRoomStore(Map<String, Object> param) throws Exception {
        //用户输入count
        Integer count = (Integer) param.get("count");
        //查出实际最小库存
        List<ItripHotelTempStore> result = this.queryRoomStore(param);
        //最小库存 >= 用户输入count
        if(EmptyUtils.isEmpty(result))
            return false;
        return result.get(0).getStore() >= count;
    }

    @Override
    public Map<String,Object> validateRoomStore2(Map<String, Object> param) throws Exception {
        //用户输入count
        Integer count = (Integer) param.get("count");
        //查出实际最小库存
        List<ItripHotelTempStore> result = this.queryRoomStore(param);
        //最小库存 >= 用户输入count
        Map<String,Object> output = new HashMap<>();
        if(EmptyUtils.isEmpty(result)){
            output.put("success",false);
            output.put("store",0);
            return output;
        }
        output.put("success",result.get(0).getStore() >= count);
        output.put("store",result.get(0).getStore());
        return output;
    }

    @Override
    public BigDecimal getOrderPayAmount(int count, long roomId) throws Exception {
        double price = itripHotelRoomMapper.getItripHotelRoomById(roomId).getRoomPrice();
        return BigDecimalUtil.OperationASMD(count, price, BigDecimalUtil.BigDecimalOprations.multiply, 2, ROUND_DOWN);
    }

    @Override
    public boolean isOffLinePaymentSupported(Long orderId) throws Exception {
        Integer payType = itripHotelOrderMapper.getPayTypeByHotelId(orderId);
        return ((2 & payType) != 0);//位运算的逻辑 10 01 11的与运算
    }
}
